﻿using System;
using System.ServiceModel;
using System.ServiceModel.Syndication;
using System.IO;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.Serialization;
using System.ServiceModel.Description;
using System.Xml.Schema;

namespace dasBlog.Storage
{
    [DataContract(Namespace = Names.DataContractNamespace)]
    public enum MonikerMatch
    {
        [EnumMember]
        Exact,
        [EnumMember]
        Prefix
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public enum SerializationMode
    {
        [EnumMember]
        Native,
        [EnumMember]
        Rss,
        [EnumMember]
        Atom,
        [EnumMember]
        Json
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public class StorageNodeUnknownContext
    {
        [DataMember]
        public Moniker ContextId { get; set; }
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public class StorageNodeUnknownQuery
    {
        [DataMember]
        public string QueryName { get; set; }
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public class StorageNodeUnknownAggregateProperty
    {
        [DataMember]
        public string PropertyName { get; set; }
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public class StorageNodeItemNotFound
    {
        [DataMember]
        public Moniker ItemId { get; set; }
    }

    [DataContract(Namespace = Names.DataContractNamespace)]
    public class StorageNodeInvalidSchemaId
    {
        [DataMember]
        public string SchemaId { get; set; }
    }

    
    [ServiceContract(Name=Names.IStorageNodeName, Namespace = Names.IStorageNodeNamespace)]
    public interface IStorageNode  
    {
        [OperationContract]
        [FaultContract(typeof(StorageNodeInvalidSchemaId))]
        Message GetItemSchema(string baseUri, string schemaId);

        [OperationContract]
        [FaultContract(typeof(StorageNodeUnknownContext))]
        [FaultContract(typeof(StorageNodeUnknownQuery))]
        Message Select(string baseUri, Moniker moniker, MonikerMatch match, QueryDescription query, SerializationMode serializationMode);

        [OperationContract]
        [FaultContract(typeof(StorageNodeUnknownContext))]
        [FaultContract(typeof(StorageNodeUnknownAggregateProperty))]
        Message Aggregate(string baseUri, Moniker moniker, MonikerMatch match, string propertyName, SerializationMode serializationMode);
                
        [OperationContract]
        [FaultContract(typeof(StorageNodeUnknownContext))]
        Message Get(string baseUri, Moniker itemId, SerializationMode serializationMode);

        [OperationContract]
        [FaultContract(typeof(StorageNodeUnknownContext))]
        [FaultContract(typeof(StorageNodeItemNotFound))]
        void Delete(Moniker itemId);

        [OperationContract]
        [FaultContract(typeof(StorageNodeUnknownContext))]
        Moniker Store(Moniker moniker, XmlElement item, SerializationMode serializationMode);
    }

    public interface IStorageNodeChannel : IStorageNode, IClientChannel { }

    public static class EndpointContractDescription<I>
    {
        private static ContractDescription _desc = ContractDescription.GetContract(typeof(I));
        public static ContractDescription Description
        {
            get
            {
                return _desc;
            }
        }
    }
    
}
